package com.berchen.utils;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 自定义线程池
 *
 * @author chenwh
 */
public class ZdyThreadPool {

    public static void main(String[] args) {
        ThreadPoolExecutor callerExecutor = getCallerExecutor(2, 10, 10, TimeUnit.MILLISECONDS, 5);
        callerExecutor.execute(()->{});
//        for (int i = 0; i <6; i++) {
//
//            callerExecutor.execute(()->{
//                try {
//                    Thread.sleep(100);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                System.out.println(Thread.currentThread().getName());
//            });
//        }
//        System.out.println(callerExecutor.getPoolSize());
        // 如果不执行该方法，那么核心线程会一直活着等待任务的执行
        callerExecutor.shutdown();
    }


    /**
     * 自定义线程池
     * new ArrayBlockingQueue<>(10)由数组结构组成的【有界】阻塞队列。
     * CallerRunsPolicy：调用者机制 一种调节机制，该策略不会抛弃任务，也不会抛出异常，而是将任务回退到调用者，从而降低新任务的流量。
     * @param corePoolSize
     * @param maximumPoolSize
     * @param keepAliveTime
     * @param unit
     * @param capacity
     * @return
     */
    public static ThreadPoolExecutor getCallerExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, int capacity) {
        return new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                new ArrayBlockingQueue<>(capacity),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy());
    }

    /**
     * 获取直接丢弃任务的线程池  等待队列是数组类型的有界队列
     * DiscardPolicy：直接丢弃任务，不予任何处理也不抛出异常。如果允许任务丢失，这是最好的一种方案。
     *
     * @param corePoolSize      常驻核心线程数量
     * @param maximumPoolSize   线程池能够过同时执行的最大线程数，该值必须大于等于1
     * @param keepAliveTime     多余线程的空闲时间，当线程数量大于corePoolSize 并且空闲的线程空闲时间超过该值，就会被销毁多余的，直到数量=corePoolSize
     * @param unit              空闲时间的单位
     * @param capacity          等待队列的容量
     * @return
     */
    public static ThreadPoolExecutor getDiscardExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, int capacity) {
        return new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                new ArrayBlockingQueue<>(capacity),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardPolicy());
    }
}
